package org.lilystudio.veryftp.search.impl;

import java.util.List;
import java.util.HashSet;
import java.util.ArrayList;
import java.util.Iterator;

//import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;

import org.hibernate.Transaction;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;

import org.lilystudio.veryftp.model.FTPFile;
import org.lilystudio.veryftp.model.FTPSite;
import org.lilystudio.veryftp.model.ParentFile;
import org.lilystudio.veryftp.search.Search;
import static org.lilystudio.veryftp.util.WordUtil.parse;
import org.lilystudio.veryftp.analyzer.VeryAnalyzer;

/**
 * 搜索类，fullTextSession需要用spring注入
 * @author fnight
 *
 */
public class SearchImpl implements Search{
	
	/**
	 * 搜索的结果总数
	 */
	private int resultSize;
	
	/**
	 * 搜索时间
	 */
	private long searchTime;
	
	/**
	 * @see org.hibernate.search.FullTextSession
	 */
	private FullTextSession fullTextSession;	
	
	/**
	 * 搜索，返回List&lt;FTPSite&gt;
	 * @see org.lilystudio.veryftp.model.FTPSite;
	 * @see org.lilystudio.veryftp.model.FTPFile;
	 * @see org.lilystudio.veryftp.model.ParentFile;
	 */
	@SuppressWarnings("unchecked")
	public List<FTPSite> search(String searchString){	
		
		List<FTPSite> sites=null;	
		
		FullTextQuery fullTextQuery=null;
		
		Transaction tx=null;
		
		try{
			//搜索开始时间
			long startTime=System.currentTimeMillis();
			
			tx = fullTextSession.beginTransaction();
		
			QueryParser parser = new QueryParser("fileName",new VeryAnalyzer());	
			
			Query query = parser.parse(getExpression("+","fileName",searchString));
			
			fullTextQuery = fullTextSession.createFullTextQuery( query, FTPFile.class);
			
			//排序
			fullTextQuery.setSort(
					new Sort(new SortField[]{
							new SortField("parentFile.Site_siteId"),
							new SortField("parentFile.fileId"),						
							}
					)
				);			
			
			fullTextQuery.setFirstResult(0);
			
			fullTextQuery.setMaxResults(Search.MAX_RESULT_COUNT);		
			//结果总数
			resultSize=fullTextQuery.getResultSize();
			
			if(resultSize>0){
				//处理搜索结果
				sites=make(fullTextQuery.iterate());
			}	
			
			tx.commit();
			//搜索结束时间
			long endTime=System.currentTimeMillis();
			//搜索时间（单位：ms）
			searchTime=endTime-startTime;
				
		}		
		catch(Exception e){
			e.printStackTrace();
		}
		
		
		return sites;
	}
	/**
	 * 处理搜索返回的List &lt;FTPFile&gt
	 * 就是一个比对的过程，相同站点的归在同一站点下，相同目录下的归在同一parentFile下
	 * @param i (List&lt;FTPFile&gt).iterator()
	 * @return List &lt;FTPSite&gt
	 */
	public List<FTPSite> make(Iterator<FTPFile> i){
		
		List<FTPSite> result=new ArrayList<FTPSite>();
		FTPFile file=i.next();
		
		FTPSite site=new FTPSite(file.getParentFile().getDownSite());
		
		ParentFile parentFile=new ParentFile(file.getParentFile());
		
		parentFile.setChildFiles(new HashSet<FTPFile>());
		parentFile.setDownSite(site);
		
		parentFile.getChildFiles().add(new FTPFile(file));
		
		while(i.hasNext()){
			file=i.next();
			if(file.getParentFile().getDownSite().getSiteId()==site.getSiteId()){
				if(file.getParentFile().getFileId()==parentFile.getFileId()){
					parentFile.getChildFiles().add(file);
				}
				else{
					site.getFiles().add(parentFile);
					parentFile=new ParentFile(file.getParentFile());		
					parentFile.setDownSite(site);
					parentFile.getChildFiles().add(new FTPFile(file));
				}
			}
			else{
				site.getFiles().add(parentFile);
				
				result.add(site);
				site=new FTPSite(file.getParentFile().getDownSite());
				
				parentFile=new ParentFile(file.getParentFile());
				parentFile.setDownSite(site);
				
				parentFile.getChildFiles().add(file);
			}
			
		}
		site.getFiles().add(parentFile);
		
		result.add(site);
		
		return result;
	}
	/**
	 * 获得搜索解析式
	 * @param op 操作符（+为并，-为非，无为或）
	 * @param fieldName 搜索的FieldName
	 * @param searchString 搜索输入的字符串，未做任何处理
	 * @return 搜索解析式
	 */
	public String getExpression(String op,String fieldName,String searchString){
		
		String[] tokens=parse(searchString).split(" ");
		
		StringBuilder result=new StringBuilder();
		
		for(String token:tokens){
			result.append(op+fieldName+":"+token+"* ");
		}

		return result.toString();
	}
	
	
	/**
	 * 获得搜索的结果总数
	 */
	public int getResultSize(){
		return resultSize;
	}
	/**
	 * 获得搜索时间
	 */
	public long getSearchTime(){
		return searchTime;
	}
	
	public FullTextSession getFullTextSession() {
		return fullTextSession;
	}
	public void setFullTextSession(FullTextSession fullTextSession) {
		this.fullTextSession = fullTextSession;
	}
	

}

